package com.scpii.api.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import com.scpii.api.common.Constants;
import com.scpii.api.domain.content.Resources;

public class FileUtil {

	private static final Logger logger = Logger.getLogger(FileUtil.class);

	public static List<Resources> save(MultipartFile[] files) {
		List<Resources> resourcesArr = new ArrayList<Resources>();
		if (files == null) {
			return resourcesArr;
		}
		for (int i = 0; i < files.length; i++) {
			Resources resources = save(files[i]);
			if (resources != null) {
				resourcesArr.add(resources);
			}
		}
		return resourcesArr;
	}

	public static List<Resources> save(MultipartFile[] files, String title,
			Long targetId) {
		List<Resources> resourcesArr = new ArrayList<Resources>();
		if (files == null) {
			return resourcesArr;
		}
		for (int i = 0; i < files.length; i++) {
			Resources resources = save(files[i], title, targetId);
			if (resources != null) {
				resourcesArr.add(resources);
			}
		}
		return resourcesArr;
	}

	public static List<Resources> save(MultipartFile[] files, String title) {
		List<Resources> resourcesArr = new ArrayList<Resources>();
		if (files == null) {
			return resourcesArr;
		}
		for (int i = 0; i < files.length; i++) {
			Resources resources = save(files[i], title, null);
			if (resources != null) {
				resourcesArr.add(resources);
			}
		}
		return resourcesArr;
	}

	public static Resources save(MultipartFile file) {
		return save(file, null, null);
	}

	public static Resources save(MultipartFile file, String title, Long targetId) {
		if (file == null || file.isEmpty()) {
			return null;
		}
		logger.info("save file " + file.getOriginalFilename() + " in progress");
		String originalFileName = file.getOriginalFilename();
		String fileExtension = StringUtils.substringAfterLast(originalFileName,
				".").toLowerCase();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
		String dateString = simpleDateFormat.format(new Date());
		String saveFileName = CommonUtil.getUUID() + "." + fileExtension;
		String saveThumbFileName = CommonUtil.getUUID() + "." + fileExtension;

		String filePrefix = "other";
		if (ArrayUtils.contains(Constants.RESOURCE_TYPES_IMAGES, fileExtension)) {
			filePrefix = "images";
		} else if (ArrayUtils.contains(Constants.RESOURCE_TYPES_VIDEOS,
				fileExtension)) {
			filePrefix = "videos";
		} else if (!StringUtils.isBlank(fileExtension)) {
			filePrefix = fileExtension + "s";
		}
		String saveFilePath = Constants.RESOURCE_ROOT_PATH + File.separator
				+ filePrefix + File.separator + dateString + File.separator
				+ saveFileName;
		File saveFile = new File(saveFilePath);
		File saveFileParentFile = saveFile.getParentFile();
		if (!saveFileParentFile.exists()) {
			saveFileParentFile.mkdirs();
		}
		String saveThumbImageFilePath = Constants.RESOURCE_ROOT_PATH
				+ File.separator + filePrefix + File.separator + dateString
				+ File.separator + saveThumbFileName;
		File saveThumbImageFile = new File(saveThumbImageFilePath);
		File saveThumbImageParentFile = saveThumbImageFile.getParentFile();
		if (!saveThumbImageParentFile.exists()) {
			saveThumbImageParentFile.mkdirs();
		}
		try {
			if ("images".equals(filePrefix)) {
				byte[] fileByteArray = file.getBytes();
				fileByteArray = ImageUtil.resizeImage(fileByteArray,
						Constants.IMAGE_MAX_DIM);
				FileUtils.writeByteArrayToFile(saveThumbImageFile,
						fileByteArray);
			}
			FileUtils.writeByteArrayToFile(saveFile, file.getBytes());
		} catch (IOException e) {
			if (logger.isDebugEnabled()) {
				logger.debug(
						"Could  not save file " + file.getOriginalFilename(), e);
			}
			return null;
		}

		String saveFileUrl = "/" + filePrefix + "/" + dateString + "/"
				+ saveFileName;
		String saveThumbImageUrl = "/" + filePrefix + "/" + dateString + "/"
				+ saveThumbFileName;
		logger.info(file.getOriginalFilename() + " saved URL is " + saveFileUrl);
		Resources resources = new Resources();
		resources.setCreateDt(new Date());
		resources.setCreateBy(PrincipalUtil.getPrincipal().getId());
		resources.setMediaType(StringUtils.substringBefore(filePrefix, "s")
				.toUpperCase());
		resources.setTitle(title);
		resources.setThumbImage(saveThumbImageUrl);
		resources.setMediaUrl(saveFileUrl);
		resources.setTargetId(targetId);
		return resources;
	}

	public static File writeTempFile(MultipartFile file) {
		if (file == null || file.isEmpty()) {
			return null;
		}
		File parentFile = new File(System.getProperty("java.io.tmpdir"));
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		String tempFileName = CommonUtil.getUUID();
		File saveFile = new File(System.getProperty("java.io.tmpdir")
				+ File.separator + tempFileName);
		try {
			FileUtils.writeByteArrayToFile(saveFile, file.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return saveFile;
	}

	public static void readToBuffer(StringBuffer buffer, byte[] fileByte) {
		InputStream is = new ByteArrayInputStream(fileByte);
		String line;
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		try {
			line = reader.readLine();
			while (line != null) {
				buffer.append(line);
				buffer.append("\n");
				line = reader.readLine();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				reader.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
				// eat it
			}
		}
	}

	public static String readFileToString(MultipartFile file) {
		if (file == null || file.isEmpty()) {
			return null;
		}
		File saveFile = writeTempFile(file);
		String content = null;
		try {
			content = FileUtils.readFileToString(saveFile, "UTF-8");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			saveFile.deleteOnExit();
		}
		return content;
	}

	public static String readFileToStringEnd(MultipartFile file, Integer length) {
		String str = readFileToString(file);
		return StringUtils.substring(str, -length);
	}
}
